package com.cn.transfer.common.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cn.transfer.common.constant.KeyConstant;
import com.cn.transfer.common.utils.exception.BizException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;

import java.lang.reflect.Field;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author: 向伟典
 * @date: 2023/8/31 15:51
 * @Description: 工具类
 */
public class ConnmeUtils {

    public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) {
        String jsonStr = JSONUtil.toJsonStr(map);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.readValue(jsonStr, clazz);
        } catch (JsonProcessingException e) {
            throw new BizException("在转换BizContent集合是出现了错误，对象为"+clazz);
        }
    }
    public static Header[] createHeaders() {
        Header[] headers = new Header[2];
        headers[0] = new BasicHeader("Authorization", "Bearer " + KeyConstant.JDY_KEY);
        headers[1] = new BasicHeader("Content-Type", "application/json;charset=utf-8");
        return headers;
    }

    /**
     * 根据对象，获取简道云传输格式
     */
    public static Map<String, Object> convertEntityToMap(Object entity) {
        Map<String, Object> data = new HashMap<>();
        Class<?> clazz = entity.getClass();

        try {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(entity);

                // 将字段名转换为小写
                String fieldName = field.getName().toLowerCase();

                // 如果字段值是列表类型（List 或其他集合类型），递归处理每个列表项
                if (value instanceof List<?>) {
                    // 如果字段值是列表类型，将列表作为一个值添加到 data 中
                    List<Map<String, Object>> listData = new ArrayList<>();
                    for (Object listItem : (List<?>) value) {
                        listData.add(convertEntityToMap(listItem));
                    }
                    Map<String,Object> mapData = new HashMap<>();
                    mapData.put("value", listData);
                    data.put(fieldName, mapData);
                } else if (value instanceof Map<?, ?>) {
                    // 如果字段值是 Map 类型，递归处理每个子项
                    Map<String, Object> mapData = new HashMap<>();
                    for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
                        Object mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        if (mapValue instanceof List<?>) {
                            List<Map<String, Object>> listData = new ArrayList<>();
                            for (Object listItem : (List<?>) mapValue) {
                                Map<String, Object> listItemMap = new HashMap<>();
                                listItemMap.put("value", listItem != null ? listItem : "");
                                listData.add(listItemMap);
                            }
                            mapData.put(mapKey.toString(), listData);
                        } else {
                            mapData.put(mapKey.toString(), mapValue != null ? mapValue : "");
                        }
                    }
                    data.put(fieldName, mapData);
                } else {
                    // 否则，将字段值作为单个属性添加到 data 中
                    Map<String, Object> pa=new HashMap<String, Object>();
                    pa.put("value",value);
                    data.put(fieldName, pa);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return data;
    }

    /**
     * 比较两个对象是否相等
     */
    public static boolean deepEquals(Object obj1, Object obj2) {
        // 检查是否为null
        if (obj1 == null || obj2 == null) {
            return false;
        }

        // 检查对象是否为同一类型
        if (!obj1.getClass().equals(obj2.getClass())) {
            return false;
        }

        // 获取对象的所有字段
        Field[] fields = obj1.getClass().getDeclaredFields();

        try {
            for (Field field : fields) {
                field.setAccessible(true);

                // 获取字段的值
                Object value1 = field.get(obj1);
                Object value2 = field.get(obj2);

                // 递归比较集合对象
                if (value1 instanceof Collection && value2 instanceof Collection) {
                    if (!deepCollectionEquals((Collection<?>) value1, (Collection<?>) value2)) {
                        return false;
                    }
                } else if (!Objects.equals(value1, value2)) {
                    return false;
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private static boolean deepCollectionEquals(Collection<?> collection1, Collection<?> collection2) {
        if (collection1.size() != collection2.size()) {
            return false;
        }

        // 检查集合中的元素是否相等
        for (Object element1 : collection1) {
            boolean found = false;
            for (Object element2 : collection2) {
                if (deepEquals(element1, element2)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                return false;
            }
        }

        return true;
    }


    public static String gettoken(){
        HttpRequest post = HttpRequest.get(" https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwfe95ca727f125b88&corpsecret=6VX1EQzZKm_Sj2Jqqev75a7gOEhBM-33G4vsCoSL21c");
        String body = post.execute().body();
        JSONObject entries = JSONUtil.parseObj(body);
        return entries.getStr("access_token");
    }

    public static String getJandaoyyunToken(){
        HttpRequest post = HttpRequest.get(" https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwfe95ca727f125b88&corpsecret=DFX-kGgtV7oMM3CixBjzfHHxKjS2RcjoJrDfwWMIFwg");
        String body = post.execute().body();
        JSONObject entries = JSONUtil.parseObj(body);
        return entries.getStr("access_token");
    }

    public static Map<String, Object> convertEntityToMapNull(Object entity) {
        Map<String, Object> data = new HashMap<>();
        Class<?> clazz = entity.getClass();

        try {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(entity);

                // 将字段名转换为小写
                String fieldName = field.getName().toLowerCase();

                // 跳过 null 值的字段
                if (value == null) {
                    continue;
                }

                // 如果字段值是列表类型（List 或其他集合类型），递归处理每个列表项
                if (value instanceof List<?>) {
                    // 如果字段值是列表类型，将列表作为一个值添加到 data 中
                    List<Map<String, Object>> listData = new ArrayList<>();
                    for (Object listItem : (List<?>) value) {
                        listData.add(convertEntityToMapNull(listItem));
                    }
                    Map<String,Object> mapData = new HashMap<>();
                    mapData.put("value", listData);
                    data.put(fieldName, mapData);
                } else if (value instanceof Map<?, ?>) {
                    // 如果字段值是 Map 类型，递归处理每个子项
                    Map<String, Object> mapData = new HashMap<>();
                    for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
                        Object mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        if (mapValue instanceof List<?>) {
                            List<Map<String, Object>> listData = new ArrayList<>();
                            for (Object listItem : (List<?>) mapValue) {
                                Map<String, Object> listItemMap = new HashMap<>();
                                listItemMap.put("value", listItem != null ? listItem : "");
                                listData.add(listItemMap);
                            }
                            mapData.put(mapKey.toString(), listData);
                        } else {
                            mapData.put(mapKey.toString(), mapValue != null ? mapValue : "");
                        }
                    }
                    data.put(fieldName, mapData);
                } else {
                    // 否则，将字段值作为单个属性添加到 data 中
                    Map<String, Object> pa = new HashMap<>();
                    pa.put("value", value);
                    data.put(fieldName, pa);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return data;
    }
    public static String extractTimestamp(String dateString) {
        //
        String timestamp = dateString.replaceAll("^/Date\\((\\d+)([\\+\\-]\\d+)?\\)/$", "$1");
        return timestamp;
    }

    /**
     * // 从时间戳转换为 Instant，再转换为 LocalDateTime
     * @param timestamp
     * @return
     */
    public static LocalDateTime convertTimestampToLocalDateTime(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * 定义日期时间格式
     * @param dateTime
     * @return
     */
    public static String formatDateTime(LocalDateTime dateTime) {
        //
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTime.format(formatter);
    }

}
